if ( !self::$dbSetup ) {
// switch to a temporary clone of the database
self::setupTestDB( $this->db, $this->dbPrefix() );
+ $this->addCoreDBData();
if ( ( $this->db->getType() == 'oracle' || !self::$useTemporaryTables ) && self::$reuseDB ) {
$this->resetDB();
}
}
- $this->addCoreDBData();
+
+ // TODO: the DB setup should be done in setUpBeforeClass(), so the test DB
+ // is available in subclasse's setUpBeforeClass() and setUp() methods.
+ // This would also remove the need for the HACK that is oncePerClass().
+ if ( $this->oncePerClass() ) {
+ $this->addDBDataOnce();
+ }
+
$this->addDBData();
$needsResetDB = true;
}
}
}
+ /**
+ * @return boolean
+ */
+ private function oncePerClass() {
+ // Remember current test class in the database connection,
+ // so we know when we need to run addData.
+
+ $class = static::class;
+
+ $first = !isset( $this->db->_hasDataForTestClass )
+ || $this->db->_hasDataForTestClass !== $class;
+
+ $this->db->_hasDataForTestClass = $class;
+ return $first;
+ }
+
/**
* @since 1.21
*
}
/**
- * Stub. If a test needs to add additional data to the database, it should
- * implement this method and do so
+ * Stub. If a test suite needs to add additional data to the database, it should
+ * implement this method and do so. This method is called once per test suite
+ * (i.e. once per class).
+ *
+ * Note data added by this method may be removed by resetDB() depending on
+ * the contents of $tablesUsed.
+ *
+ * To add additional data between test function runs, override prepareDB().
+ *
+ * @see addDBData()
+ * @see resetDB()
+ *
+ * @since 1.27
+ */
+ public function addDBDataOnce() {
+ }
+
+ /**
+ * Stub. Subclasses may override this to prepare the database.
+ * Called before every test run (test function or data set).
+ *
+ * @see addDBDataOnce()
+ * @see resetDB()
*
* @since 1.18
*/
*/
private function resetDB() {
if ( $this->db ) {
- if ( $this->db->getType() == 'oracle' ) {
- if ( self::$useTemporaryTables ) {
- wfGetLB()->closeAll();
- $this->db = wfGetDB( DB_MASTER );
- } else {
- foreach ( $this->tablesUsed as $tbl ) {
- if ( $tbl == 'interwiki' ) {
- continue;
- }
- $this->db->query( 'TRUNCATE TABLE ' . $this->db->tableName( $tbl ), __METHOD__ );
- }
+ $truncate = in_array( $this->db->getType(), [ 'oracle', 'mysql' ] );
+ foreach ( $this->tablesUsed as $tbl ) {
+ // TODO: reset interwiki and user tables to their original content.
+ if ( $tbl == 'interwiki' || $tbl == 'user' ) {
+ continue;
}
- } else {
- foreach ( $this->tablesUsed as $tbl ) {
- if ( $tbl == 'interwiki' || $tbl == 'user' ) {
- continue;
- }
+
+ if ( $truncate ) {
+ $this->db->query( 'TRUNCATE TABLE ' . $this->db->tableName( $tbl ), __METHOD__ );
+ } else {
$this->db->delete( $tbl, '*', __METHOD__ );
}
}
public static function wfResetOutputBuffersBarrier( $buffer ) {
return $buffer;
}
+
}
private $blockId;
function addDBData() {
-
$user = User::newFromName( 'UTBlockee' );
if ( $user->getID() == 0 ) {
$user->addToDatabase();
/**
* Make some pages to work with
*/
- public function addDBData() {
+ public function addDBDataOnce() {
// Pages that won't actually be merged
$this->insertPage( 'Test' );
$this->insertPage( 'Test2' );
*/
class PrefixSearchTest extends MediaWikiLangTestCase {
- public function addDBData() {
+ public function addDBDataOnce() {
if ( !$this->isWikitextNS( NS_MAIN ) ) {
// tests are skipped if NS_MAIN is not wikitext
return;
CONTENT_MODEL_WIKITEXT
);
}
+
+ $this->tablesUsed[] = 'archive';
}
protected function tearDown() {
return $this->getTokenList( self::$users['sysop'] );
}
- function addDBData() {
+ function addDBDataOnce() {
$user = User::newFromName( 'UTApiBlockee' );
if ( $user->getId() == 0 ) {
/**
* Create a set of pages. These must not change, otherwise the tests might give wrong results.
- * @see MediaWikiTestCase::addDBData()
+ *
+*@see MediaWikiTestCase::addDBDataOnce()
*/
- function addDBData() {
+ function addDBDataOnce() {
try {
if ( Title::newFromText( 'AQBT-All' )->exists() ) {
return;
/**
* Create a set of pages. These must not change, otherwise the tests might give wrong results.
- * @see MediaWikiTestCase::addDBData()
+ *
+*@see MediaWikiTestCase::addDBDataOnce()
*/
- function addDBData() {
+ function addDBDataOnce() {
try {
$this->editPage( 'AQCT73462-A', '**AQCT73462-A** [[AQCT73462-B]] [[AQCT73462-C]]' );
$this->editPage( 'AQCT73462-B', '[[AQCT73462-A]] **AQCT73462-B** [[AQCT73462-C]]' );
/**
* Create a set of pages. These must not change, otherwise the tests might give wrong results.
- * @see MediaWikiTestCase::addDBData()
+ *
+*@see MediaWikiTestCase::addDBDataOnce()
*/
- function addDBData() {
+ function addDBDataOnce() {
try {
$this->editPage( 'Template:AQCT-T1', '**Template:AQCT-T1**' );
$this->editPage( 'Template:AQCT-T2', '**Template:AQCT-T2**' );
*/
class GenderCacheTest extends MediaWikiLangTestCase {
- function addDBData() {
+ function addDBDataOnce() {
// ensure the correct default gender
$this->mergeMwGlobalArrayValue( 'wgDefaultUserOptions', [ 'gender' => 'unknown' ] );
$this->setContentLang( 'de' );
}
- function addDBData() {
+ function addDBDataOnce() {
$this->configureLanguages();
// Set up messages and fallbacks ab -> ru -> de
*/
private static $mockRecentChange;
+ /**
+ * @var Revision
+ */
+ private static $pageRev = null;
+
+ /**
+ * @var string
+ */
+ private static $pageName = 'CategoryMembershipChangeTestPage';
+
public static function newForCategorizationCallback() {
self::$lastNotifyArgs = func_get_args();
self::$notifyCallCounter += 1;
parent::setUp();
self::$notifyCallCounter = 0;
self::$mockRecentChange = self::getMock( 'RecentChange' );
+
+ $this->setContentLang( 'qqx' );
+ }
+
+ public function addDBDataOnce() {
+ $info = $this->insertPage( self::$pageName );
+ $title = $info['title'];
+
+ $page = WikiPage::factory( $title );
+ self::$pageRev = $page->getRevision();
}
private function newChange( Revision $revision = null ) {
- $change = new CategoryMembershipChange( Title::newFromText( 'UTPage' ), $revision );
+ $change = new CategoryMembershipChange( Title::newFromText( self::$pageName ), $revision );
$change->overrideNewForCategorizationCallback(
'CategoryMembershipChangeTest::newForCategorizationCallback'
);
$this->assertTrue( strlen( self::$lastNotifyArgs[0] ) === 14 );
$this->assertEquals( 'Category:CategoryName', self::$lastNotifyArgs[1]->getPrefixedText() );
- $this->assertEquals( 'MediaWiki automatic change', self::$lastNotifyArgs[2]->getName() );
- $this->assertEquals( '[[:UTPage]] added to category', self::$lastNotifyArgs[3] );
- $this->assertEquals( 'UTPage', self::$lastNotifyArgs[4]->getPrefixedText() );
+ $this->assertEquals( '(autochange-username)', self::$lastNotifyArgs[2]->getName() );
+ $this->assertEquals( '(recentchanges-page-added-to-category: ' . self::$pageName . ', 0)',
+ self::$lastNotifyArgs[3] );
+ $this->assertEquals( self::$pageName, self::$lastNotifyArgs[4]->getPrefixedText() );
$this->assertEquals( 0, self::$lastNotifyArgs[5] );
$this->assertEquals( 0, self::$lastNotifyArgs[6] );
$this->assertEquals( null, self::$lastNotifyArgs[7] );
$this->assertTrue( strlen( self::$lastNotifyArgs[0] ) === 14 );
$this->assertEquals( 'Category:CategoryName', self::$lastNotifyArgs[1]->getPrefixedText() );
- $this->assertEquals( 'MediaWiki automatic change', self::$lastNotifyArgs[2]->getName() );
- $this->assertEquals( '[[:UTPage]] removed from category', self::$lastNotifyArgs[3] );
- $this->assertEquals( 'UTPage', self::$lastNotifyArgs[4]->getPrefixedText() );
+ $this->assertEquals( '(autochange-username)', self::$lastNotifyArgs[2]->getName() );
+ $this->assertEquals( '(recentchanges-page-removed-from-category: ' . self::$pageName . ', 0)',
+ self::$lastNotifyArgs[3] );
+ $this->assertEquals( self::$pageName, self::$lastNotifyArgs[4]->getPrefixedText() );
$this->assertEquals( 0, self::$lastNotifyArgs[5] );
$this->assertEquals( 0, self::$lastNotifyArgs[6] );
$this->assertEquals( null, self::$lastNotifyArgs[7] );
}
public function testChangeAddedWithRev() {
- $revision = Revision::newFromId( Title::newFromText( 'UTPage' )->getLatestRevID() );
+ $revision = Revision::newFromId( Title::newFromText( self::$pageName )->getLatestRevID() );
$change = $this->newChange( $revision );
$change->triggerCategoryAddedNotification( Title::newFromText( 'CategoryName', NS_CATEGORY ) );
$this->assertTrue( strlen( self::$lastNotifyArgs[0] ) === 14 );
$this->assertEquals( 'Category:CategoryName', self::$lastNotifyArgs[1]->getPrefixedText() );
$this->assertEquals( 'UTSysop', self::$lastNotifyArgs[2]->getName() );
- $this->assertEquals( '[[:UTPage]] added to category', self::$lastNotifyArgs[3] );
- $this->assertEquals( 'UTPage', self::$lastNotifyArgs[4]->getPrefixedText() );
- $this->assertEquals( 0, self::$lastNotifyArgs[5] );
+ $this->assertEquals( '(recentchanges-page-added-to-category: ' . self::$pageName . ', 0)',
+ self::$lastNotifyArgs[3] );
+ $this->assertEquals( self::$pageName, self::$lastNotifyArgs[4]->getPrefixedText() );
+ $this->assertEquals( self::$pageRev->getParentId(), self::$lastNotifyArgs[5] );
$this->assertEquals( $revision->getId(), self::$lastNotifyArgs[6] );
$this->assertEquals( null, self::$lastNotifyArgs[7] );
$this->assertEquals( 0, self::$lastNotifyArgs[8] );
}
public function testChangeRemovedWithRev() {
- $revision = Revision::newFromId( Title::newFromText( 'UTPage' )->getLatestRevID() );
+ $revision = Revision::newFromId( Title::newFromText( self::$pageName )->getLatestRevID() );
$change = $this->newChange( $revision );
$change->triggerCategoryRemovedNotification( Title::newFromText( 'CategoryName', NS_CATEGORY ) );
$this->assertTrue( strlen( self::$lastNotifyArgs[0] ) === 14 );
$this->assertEquals( 'Category:CategoryName', self::$lastNotifyArgs[1]->getPrefixedText() );
$this->assertEquals( 'UTSysop', self::$lastNotifyArgs[2]->getName() );
- $this->assertEquals( '[[:UTPage]] removed from category', self::$lastNotifyArgs[3] );
- $this->assertEquals( 'UTPage', self::$lastNotifyArgs[4]->getPrefixedText() );
- $this->assertEquals( 0, self::$lastNotifyArgs[5] );
+ $this->assertEquals( '(recentchanges-page-removed-from-category: ' . self::$pageName . ', 0)',
+ self::$lastNotifyArgs[3] );
+ $this->assertEquals( self::$pageName, self::$lastNotifyArgs[4]->getPrefixedText() );
+ $this->assertEquals( self::$pageRev->getParentId(), self::$lastNotifyArgs[5] );
$this->assertEquals( $revision->getId(), self::$lastNotifyArgs[6] );
$this->assertEquals( null, self::$lastNotifyArgs[7] );
$this->assertEquals( 0, self::$lastNotifyArgs[8] );
foreach ( $versions as $version ) {
$versions = "upgrading from $version to $wgVersion";
- $db = $this->prepareDB( $version );
+ $db = $this->prepareTestDB( $version );
$tables = $this->getTables( $db );
$this->assertEquals( $currentTables, $tables, "Different tables $versions" );
foreach ( $tables as $table ) {
$this->assertTrue( $db->close(), "closing database" );
}
- private function prepareDB( $version ) {
+ private function prepareTestDB( $version ) {
static $maint = null;
if ( $maint === null ) {
$maint = new FakeMaintenance();
* ^--- make sure temporary tables are used.
*/
class LinksUpdateTest extends MediaWikiLangTestCase {
- protected $testingPageId;
+ protected static $testingPageId;
function __construct( $name = null, array $data = [], $dataName = '' ) {
parent::__construct( $name, $data, $dataName );
$this->setMwGlobals( 'wgRCWatchCategoryMembership', true );
}
- public function addDBData() {
+ public function addDBDataOnce() {
$res = $this->insertPage( 'Testing' );
- $this->testingPageId = $res['id'];
+ self::$testingPageId = $res['id'];
$this->insertPage( 'Some_other_page' );
$this->insertPage( 'Template:TestingTemplate' );
}
public function testUpdate_pagelinks() {
/** @var Title $t */
/** @var ParserOutput $po */
- list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", $this->testingPageId );
+ list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", self::$testingPageId );
$po->addLink( Title::newFromText( "Foo" ) );
$po->addLink( Title::newFromText( "Special:Foo" ) ); // special namespace should be ignored
'pagelinks',
'pl_namespace,
pl_title',
- 'pl_from = ' . $this->testingPageId,
+ 'pl_from = ' . self::$testingPageId,
[ [ NS_MAIN, 'Foo' ] ]
);
$this->assertArrayEquals( [
'pagelinks',
'pl_namespace,
pl_title',
- 'pl_from = ' . $this->testingPageId,
+ 'pl_from = ' . self::$testingPageId,
[
[ NS_MAIN, 'Bar' ],
[ NS_TALK, 'Bar' ],
*/
public function testUpdate_externallinks() {
/** @var ParserOutput $po */
- list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", $this->testingPageId );
+ list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", self::$testingPageId );
$po->addExternalLink( "http://testing.com/wiki/Foo" );
$po,
'externallinks',
'el_to, el_index',
- 'el_from = ' . $this->testingPageId,
+ 'el_from = ' . self::$testingPageId,
[
[ 'http://testing.com/wiki/Foo', 'http://com.testing./wiki/Foo' ],
]
/** @var ParserOutput $po */
$this->setMwGlobals( 'wgCategoryCollation', 'uppercase' );
- list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", $this->testingPageId );
+ list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", self::$testingPageId );
$po->addCategory( "Foo", "FOO" );
$po,
'categorylinks',
'cl_to, cl_sortkey',
- 'cl_from = ' . $this->testingPageId,
+ 'cl_from = ' . self::$testingPageId,
[ [ 'Foo', "FOO\nTESTING" ] ]
);
}
*/
public function testUpdate_iwlinks() {
/** @var ParserOutput $po */
- list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", $this->testingPageId );
+ list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", self::$testingPageId );
$target = Title::makeTitleSafe( NS_MAIN, "Foo", '', 'linksupdatetest' );
$po->addInterwikiLink( $target );
$po,
'iwlinks',
'iwl_prefix, iwl_title',
- 'iwl_from = ' . $this->testingPageId,
+ 'iwl_from = ' . self::$testingPageId,
[ [ 'linksupdatetest', 'Foo' ] ]
);
}
*/
public function testUpdate_templatelinks() {
/** @var ParserOutput $po */
- list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", $this->testingPageId );
+ list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", self::$testingPageId );
$po->addTemplate( Title::newFromText( "Template:Foo" ), 23, 42 );
'templatelinks',
'tl_namespace,
tl_title',
- 'tl_from = ' . $this->testingPageId,
+ 'tl_from = ' . self::$testingPageId,
[ [ NS_TEMPLATE, 'Foo' ] ]
);
}
*/
public function testUpdate_imagelinks() {
/** @var ParserOutput $po */
- list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", $this->testingPageId );
+ list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", self::$testingPageId );
$po->addImage( "Foo.png" );
$po,
'imagelinks',
'il_to',
- 'il_from = ' . $this->testingPageId,
+ 'il_from = ' . self::$testingPageId,
[ [ 'Foo.png' ] ]
);
}
] );
/** @var ParserOutput $po */
- list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", $this->testingPageId );
+ list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", self::$testingPageId );
$po->addLanguageLink( Title::newFromText( "en:Foo" )->getFullText() );
$po,
'langlinks',
'll_lang, ll_title',
- 'll_from = ' . $this->testingPageId,
+ 'll_from = ' . self::$testingPageId,
[ [ 'En', 'Foo' ] ]
);
}
global $wgPagePropsHaveSortkey;
/** @var ParserOutput $po */
- list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", $this->testingPageId );
+ list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", self::$testingPageId );
$fields = [ 'pp_propname', 'pp_value' ];
$expected = [];
}
$this->assertLinksUpdate(
- $t, $po, 'page_props', $fields, 'pp_page = ' . $this->testingPageId, $expected );
+ $t, $po, 'page_props', $fields, 'pp_page = ' . self::$testingPageId, $expected );
}
public function testUpdate_page_props_without_sortkey() {
public function setUp() {
parent::setUp();
$this->setMwGlobals( 'wgRCWatchCategoryMembership', true );
+ $this->setContentLang( 'qqx' );
}
- public function addDBData() {
- parent::addDBData();
+ public function addDBDataOnce() {
+ parent::addDBDataOnce();
$insertResult = $this->insertPage( self::TITLE_STRING, 'UT Content' );
$this->title = $insertResult['title'];
}
$removedRevId = $this->editPageText( 'Blank' );
$this->assertEquals(
- '[[:' . self::TITLE_STRING . ']] added to category',
+ '(recentchanges-page-added-to-category: ' . self::TITLE_STRING . ', 0)',
$this->getCategorizeRecentChangeForRevId( $addedRevId )->getAttribute( 'rc_comment' )
);
$this->assertEquals(
- '[[:' . self::TITLE_STRING . ']] removed from category',
+ '(recentchanges-page-removed-from-category: ' . self::TITLE_STRING . ', 0)',
$this->getCategorizeRecentChangeForRevId( $removedRevId )->getAttribute( 'rc_comment' )
);
}
parent::tearDownAfterClass();
}
- function addDBData() {
- $this->tablesUsed[] = 'site_stats';
+ function addDBDataOnce() {
# disabled for performance
# $this->tablesUsed[] = 'image';
# Update certain things in site_stats
$this->db->insert( 'site_stats',
[ 'ss_row_id' => 1, 'ss_images' => 2, 'ss_good_articles' => 1 ],
- __METHOD__
+ __METHOD__,
+ [ 'IGNORE' ]
);
$user = User::newFromId( 0 );
*/
private $search;
- public function addDBData() {
+ public function addDBDataOnce() {
if ( !$this->isWikitextNS( NS_MAIN ) ) {
// tests are skipped if NS_MAIN is not wikitext
return;
parent::tearDown();
}
- public function addDBData() {
+ public function addDBDataOnce() {
if ( !$this->isWikitextNS( NS_MAIN ) ) {
// @todo cover the case of non-wikitext content in the main namespace
return;
] );
}
- public function addDBData() {
+ public function addDBDataOnce() {
$passwordFactory = new \PasswordFactory();
$passwordFactory->init( \RequestContext::getMain()->getConfig() );
// A is unsalted MD5 (thus fast) ... we don't care about security here, this is test only
* @covers SpecialMyLanguage
*/
class SpecialMyLanguageTest extends MediaWikiTestCase {
- public function addDBData() {
+ public function addDBDataOnce() {
$titles = [
'Page/Another',
'Page/Another/ru',